home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Eudora 1.3.1 / source / ph.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-16  |  20.9 KB  |  849 lines  |  [TEXT/MPS ]

  1. #define FILE_NUM 29
  2. /* Copyright (c) 1990-1992 by the University of Illinois Board of Trustees */
  3. /**********************************************************************
  4.  * handling the Ph panel
  5.  **********************************************************************/
  6. #pragma load EUDORA_LOAD
  7. #pragma segment Ph
  8.  
  9. /************************************************************************
  10.  * the structure for the ph window
  11.  ************************************************************************/
  12. typedef struct
  13. {
  14.     STEHandle qSTE;
  15.     STEHandle aSTE;
  16.     Rect qRect;
  17.     Rect aRect;
  18.     ControlHandle okButton;
  19.     ControlHandle fingerButton;
  20.     Str63 label;
  21.     short fallback;
  22.     MyWindowPtr win;
  23. } PhType, *PhPtr, **PhHandle;
  24. #define QSTE (*PhGlobals)->qSTE
  25. #define ASTE (*PhGlobals)->aSTE
  26. #define Win (*PhGlobals)->win
  27. #define QRect (*PhGlobals)->qRect
  28. #define ARect (*PhGlobals)->aRect
  29. #define Fallback (*PhGlobals)->fallback
  30. #define OkButton (*PhGlobals)->okButton
  31. #define FingerButton (*PhGlobals)->fingerButton
  32. #define Win (*PhGlobals)->win
  33. #define Label (*PhGlobals)->label
  34. #define QText (*(*QSTE)->te)->hText
  35. #define AText (*(*ASTE)->te)->hText
  36. #define QLen (*(*QSTE)->te)->teLength
  37. #define ALen (*(*ASTE)->te)->teLength
  38. PhHandle PhGlobals;         /* for the ph window */
  39. #define IsFinger (!UseCTB&&PrefIsSet(PREF_FINGER))
  40.  
  41. /************************************************************************
  42.  * private functions
  43.  ************************************************************************/
  44.     void PhClick(MyWindowPtr win, EventRecord *event);
  45.     void PhKey(MyWindowPtr win, EventRecord *event);
  46.     Boolean PhMenu(MyWindowPtr win, int menu, int item, short modifiers);
  47.     void PhUpdate(MyWindowPtr win);
  48.     void PhCursor(Point mouse);
  49.     void PhDidResize(MyWindowPtr win, Rect *oldContR);
  50.     void PerformQuery(Boolean isPh);
  51.     void PhButton(MyWindowPtr win,ControlHandle button,long modifiers,short part);
  52.     Boolean PhClose(MyWindowPtr win);
  53.     int QiLine(short *ordinal, UPtr text, long *size);
  54.     short ContactQi(void);
  55.     short SendQiCommand(UPtr cmd);
  56.     short GetQiResponse(void);
  57.     void CloseQi(void);
  58.     void PhSetSTE(STEHandle ste);
  59.     void DoFinger(UPtr cmd);
  60.     void PhPosition(Boolean save, MyWindowPtr win);
  61.     Boolean PhApp1(MyWindowPtr win, EventRecord *event);
  62.     void PhHelp(MyWindowPtr win,Point mouse);
  63.     void IncrementPhServer(UPtr serverName);
  64.     void MakeFallbackName(UPtr serverName, short fallback);
  65.     void NotePhServer(UPtr serverName);
  66.     void PhActivate(void);
  67.  
  68. /************************************************************************
  69.  * OpenPh - open the ph window
  70.  ************************************************************************/
  71. void OpenPh(void)
  72. {
  73.     Rect r;
  74.     
  75.     CycleBalls();
  76.     if (PhGlobals)
  77.     {
  78.         SelectWindow(Win);
  79.         return;
  80.     }
  81.     if (!(PhGlobals=NewZH(PhType)))
  82.         {WarnUser(MEM_ERR,MemError()); goto fail;}
  83.         
  84.     LDRef(PhGlobals);
  85.  
  86.     if (!(Win = GetNewMyWindow(PH_WIND,nil,InFront,False,False)))
  87.         {WarnUser(MEM_ERR,MemError()); goto fail;}
  88.     if (!(OkButton = GetNewControl(PH_CNTL,Win)))
  89.         {WarnUser(MEM_ERR,MemError()); goto fail;}
  90.     if (!(FingerButton = GetNewControl(FINGER_CNTL,Win)))
  91.         {WarnUser(MEM_ERR,MemError()); goto fail;}
  92.     SetPort(Win);
  93.     TextFont(FontID);
  94.     TextSize(FontSize);
  95.     r = Win->contR;
  96.     if (!(QSTE = NewSTE(Win,&r,False,False,False)))
  97.         {WarnUser(MEM_ERR,MemError()); goto fail;}
  98.     if (!(ASTE = NewSTE(Win,&r,False,True,False)))
  99.         {WarnUser(MEM_ERR,MemError()); goto fail;}
  100.     UL(PhGlobals);
  101.     NewPhHost();
  102.     Win->close = PhClose;
  103.     Win->activate = PhActivate;
  104.     Win->click = PhClick;
  105.     Win->cursor = PhCursor;
  106.     Win->menu = PhMenu;
  107.     Win->key = PhKey;
  108.     Win->button = PhButton;
  109.     PhSetSTE(QSTE);
  110.     Win->position = PhPosition;
  111.     Win->dontControl = True;
  112.     Win->vPitch = FontLead;
  113.     Win->qWindow.windowKind = PH_WIN;
  114.     Win->update = PhUpdate;
  115.     Win->app1 = PhApp1;
  116.     Win->help = PhHelp;
  117.     Win->minSize.h = 300;
  118.     Win->minSize.v = 8*FontLead;
  119.     Win->didResize = PhDidResize;
  120.     MyWindowDidResize(Win,&r);
  121.     ShowMyWindow(Win);
  122.     ShowControl(OkButton);
  123.     ShowControl(FingerButton);
  124.     return;
  125.  
  126. fail:
  127.     PhClose(Win);
  128.     return;
  129. }
  130.  
  131.  
  132. /************************************************************************
  133.  * 
  134.  ************************************************************************/
  135. void PhActivate(void)
  136. {
  137.     OutlineControl(IsFinger ? FingerButton : OkButton,!InBG&&Win->isActive);
  138.     (*FingerButton)->contrlRfCon = UseCTB ? 'GREY' : 0;
  139. }
  140.  
  141. /************************************************************************
  142.  * PhPosition - ph window position
  143.  ************************************************************************/
  144. void PhPosition(Boolean save, MyWindowPtr win)
  145. {
  146.     Str31 ph;
  147.     MyGetItem(GetMHandle(SPECIAL_MENU),SPECIAL_PH_ITEM,ph);
  148.     SetWTitle(Win,ph);
  149.     PositionPrefsTitle(save,win);
  150. }
  151.  
  152. /************************************************************************
  153.  * PhButton - handle a button click in the ph window
  154.  ************************************************************************/
  155. void PhButton(MyWindowPtr win,ControlHandle button,long modifiers,short part)
  156. {
  157. #pragma unused(win,modifiers)
  158.     if (part==inButton) PerformQuery(button==OkButton);
  159.     Win->hasSelection = MyWinHasSelection(win);
  160. }
  161.  
  162. /************************************************************************
  163.  * PhClick - handle a click in the ph window
  164.  ************************************************************************/
  165. void PhClick(MyWindowPtr win, EventRecord *event)
  166. {
  167.     Rect r;
  168.     Point mouse = event->where;
  169.     TEHandle newTeh=nil;
  170.     
  171.     GlobalToLocal(&mouse);
  172.     
  173.     r = QRect;
  174.     if (PtInRect(mouse,&r))
  175.     {
  176.         PhSetSTE(QSTE);
  177.         STEClick(QSTE,event);
  178.     }
  179.     else
  180.     {
  181.         r = ARect;
  182.         if (PtInRect(mouse,&r))
  183.         {
  184.             PhSetSTE(ASTE);
  185.             STEClick(ASTE,event);
  186.       }
  187.         else HandleControl(mouse,win);
  188.     }
  189.     Win->hasSelection = MyWinHasSelection(win);
  190. }
  191.  
  192. /************************************************************************
  193.  * PhApp1 - handle an app1 event
  194.  ************************************************************************/
  195. Boolean PhApp1(MyWindowPtr win, EventRecord *event)
  196. {
  197. #pragma unused(win)
  198.     STEApp1(ASTE,event);
  199.     return(True);
  200. }
  201.  
  202. /************************************************************************
  203.  * PhKey - keystrokes in the ph window
  204.  ************************************************************************/
  205. void PhKey(MyWindowPtr win, EventRecord *event)
  206. {
  207.     short key = event->message & 0xff;
  208.  
  209.     if (event->modifiers & cmdKey) {SysBeep(20L); return;}                /* no command keys! */
  210.     if (key==returnChar || key==enterChar)
  211.     {
  212.         Undo.didClick = True;
  213.         PerformQuery(!IsFinger);
  214.         Win->hasSelection = MyWinHasSelection(win);
  215.         return;
  216.     }
  217.     else if (key==tabChar)
  218.     {
  219.         PhSetSTE(win->ste==QSTE ? ASTE:QSTE);
  220.         NoScrollTESetSelect(0,INFINITY,(*(STEHandle)win->ste)->te);
  221.     }
  222.     else if (win->ro)
  223.     {
  224.         PhSetSTE(QSTE);
  225.         NoScrollTESetSelect(0,INFINITY,(*QSTE)->te);
  226.     }
  227.     
  228.     if (key!=tabChar) TESomething(win,TEKEY,key,event->modifiers);
  229.  
  230.     Win->hasSelection = MyWinHasSelection(win);
  231. }
  232.  
  233. /************************************************************************
  234.  * PhMenu - menu selections in the ph window
  235.  ************************************************************************/
  236. Boolean PhMenu(MyWindowPtr win, int menu, int item, short modifiers)
  237. {
  238. #pragma unused(modifiers)
  239.     
  240.     switch (menu)
  241.     {
  242.         case FILE_MENU:
  243.             switch(item)
  244.             {
  245.                 case FILE_PRINT_ITEM:
  246.                 case FILE_PRINT_SELECT_ITEM:
  247.                 {
  248.                     win->txe = (*ASTE)->te;
  249.                     PrintOneMessage(win,item==FILE_PRINT_SELECT_ITEM);
  250.                     win->txe = nil;
  251.                     return(True);
  252.                 }
  253.             }
  254.             break;
  255.         case EDIT_MENU:
  256.             return(TESomething(win,item,0,modifiers));
  257.             break;
  258.     }
  259.     return(False);
  260. }
  261.  
  262. /************************************************************************
  263.  * PhUpdate - update the ph window
  264.  ************************************************************************/
  265. void PhUpdate(MyWindowPtr win)
  266. {
  267. #pragma unused(win)
  268.     Rect r;
  269.     Str63 scratch;
  270.  
  271.     STEUpdate(QSTE);
  272.     STEUpdate(ASTE);
  273.     
  274.     r = QRect;
  275.     MoveTo(r.left,r.top - 6);
  276.     PCopy(scratch,Label);
  277.     DrawString(scratch);
  278.         
  279.     /*
  280.      * outline the button
  281.      */
  282.     OutlineControl(IsFinger ? FingerButton : OkButton,!InBG&&win->isActive);
  283. }
  284.  
  285. /************************************************************************
  286.  * PhCursor - set the cursor for the ph window
  287.  ************************************************************************/
  288. void PhCursor(Point mouse)
  289. {
  290. #pragma unused(mouse)
  291.     if (!STECursor(QSTE) && !STECursor(ASTE))
  292.     {
  293.         SetMyCursor(arrowCursor);
  294.     }
  295. }    
  296.  
  297. /************************************************************************
  298.  * PhDidResize - handle resizing of the ph window
  299.  ************************************************************************/
  300. void PhDidResize(MyWindowPtr win, Rect *oldContR)
  301. {
  302. #pragma unused(win,oldContR)
  303.     Rect r;
  304.     Point p;
  305.     short hi = (*OkButton)->contrlRect.bottom - (*OkButton)->contrlRect.top;
  306.     short wi = (*OkButton)->contrlRect.right - (*OkButton)->contrlRect.left;
  307.     
  308.     /*
  309.      * put the Do It button where it belongs
  310.      */
  311.     p.h = Win->contR.right - GROW_SIZE - wi;
  312.     p.v = Win->contR.top + GROW_SIZE/2;
  313.     OFFSET_RECT(&(*FingerButton)->contrlRect,p.h-(*FingerButton)->contrlRect.left,
  314.                             p.v-(*FingerButton)->contrlRect.top);
  315.     p.v += GROW_SIZE/2 + hi;
  316.     OFFSET_RECT(&(*OkButton)->contrlRect,p.h-(*OkButton)->contrlRect.left,
  317.                             p.v-(*OkButton)->contrlRect.top);
  318.  
  319.     /*
  320.      * calculate the frame for the command box
  321.      */
  322.     r = Win->contR;
  323.     r.bottom = (*OkButton)->contrlRect.bottom;
  324.     r.top = r.bottom - FontLead - FontDescent - TE_VMARGIN*2;
  325.     OffsetRect(&r,0,-(hi-r.bottom+r.top)/2);
  326.     r.left += GROW_SIZE;
  327.     r.right = (*OkButton)->contrlRect.left - GROW_SIZE/2;
  328.     QRect = r;
  329.     
  330.     /*
  331.      * calculate the frame for the answer box
  332.      */
  333.     r.top = (*OkButton)->contrlRect.bottom + GROW_SIZE/2;
  334.     r.bottom = win->contR.bottom - GROW_SIZE+1;
  335.     r.right = win->contR.right - GROW_SIZE+1;
  336.     ARect = r;
  337.     
  338.     /*
  339.      * now for the TE's
  340.      */
  341.     r = QRect;
  342.     ResizeSTE(QSTE,&r);
  343.     r = ARect;
  344.     ResizeSTE(ASTE,&r);
  345.     InvalRect(&win->contR);
  346. }
  347.  
  348. #pragma segment Main
  349. /************************************************************************
  350.  * PhClose - close the ph window
  351.  ************************************************************************/
  352. Boolean PhClose(MyWindowPtr win)
  353. {
  354. #pragma unused(win)
  355.     if (PhGlobals)
  356.     {
  357.         if (QSTE) STEDispose(QSTE);
  358.         if (ASTE) STEDispose(ASTE);
  359.         DisposHandle(PhGlobals);
  360.         PhGlobals = nil;
  361.     }
  362.     return(True);
  363. }
  364. #pragma segment Ph
  365.  
  366. /************************************************************************
  367.  * PerformQuery - perform a ph query
  368.  ************************************************************************/
  369. void PerformQuery(Boolean isPh)
  370. {
  371.     Str255 cmd;
  372.     Str255 ph;
  373.     Handle table=nil;
  374.     short inId,outId;
  375.     
  376.     if (isPh == IsFinger)
  377.     {
  378.       Rect r;
  379.         ChangeStrn(PREF_STRN,PREF_FINGER,isPh?"\pn":"\py");
  380.         r = (*FingerButton)->contrlRect;
  381.         r.bottom = (*OkButton)->contrlRect.bottom;
  382.         InsetRect(&r,-4,-4);
  383.         InvalRect(&r);
  384.     }
  385.     NoScrollTESetSelect(0,INFINITY,(*QSTE)->te);
  386.     PhSetSTE(QSTE);
  387.     if (isPh)
  388.         MyGetItem(GetMHandle(SPECIAL_MENU),SPECIAL_PH_ITEM,ph);
  389.     else
  390.         GetRString(ph,FINGER);
  391.     if (!QLen)
  392.     {
  393.         SetWTitle(Win,ph);
  394.         return;
  395.     }
  396.     MakePStr(cmd,*QText,QLen);
  397.     PCatC(ph,':');
  398.     PCat(ph,cmd);
  399.     SetWTitle(Win,ph);
  400.     STESetText("",0,ASTE);
  401.     
  402.     /*
  403.      * install translation tables
  404.      */
  405.     if (NewTables)
  406.     {
  407.          inId = GetRLong(PREF_STRN+PREF_IN_XLATE);
  408.          outId = GetRLong(PREF_STRN+PREF_OUT_XLATE);
  409.     }
  410.     else
  411.     {
  412.         inId = TRANS_IN_TABL;
  413.         outId = TRANS_OUT_TABL;
  414.     }
  415.     if (inId && (table=GetResource('taBL',inId)))
  416.     {
  417.       HNoPurge(table);
  418.         if (TransIn = NuPtr(256)) BlockMove(*table,TransIn,256);
  419.         HPurge(table);
  420.     }
  421.     if (outId && (table=GetResource('taBL',outId)))
  422.     {
  423.         HNoPurge(table);
  424.         if (TransOut = NuPtr(256)) BlockMove(*table,TransOut,256);
  425.         HPurge(table);
  426.     }
  427.  
  428.     /*
  429.      * do it
  430.      */
  431.     if (!UseCTB || !DialThePhone())
  432.     {
  433.         if (!isPh)
  434.             DoFinger(cmd);
  435.         else if (!ContactQi())
  436.         {
  437.             if (!SendQiCommand(cmd)) GetQiResponse();
  438.             UpdateMyWindow(Win);
  439.             CloseQi();
  440.         }
  441.         DestroyTrans();
  442.     }
  443.   if (UseCTB) HangUpThePhone();
  444.     
  445.     /*
  446.      * clean up tables
  447.      */
  448.     if (TransIn) {DisposPtr(TransIn);TransIn=nil;}
  449.     if (TransOut) {DisposPtr(TransOut);TransOut=nil;}
  450. }
  451.  
  452. /************************************************************************
  453.  * ContactQi - make contact with the QI server
  454.  ************************************************************************/
  455. short ContactQi(void)
  456. {
  457.     Str255 serverName;
  458.     short port;
  459.     short err;
  460.  
  461.     MakeFallbackName(serverName,Fallback);
  462.     port = GetRLong(PH_PORT);
  463.     err=ConnectTrans(serverName,port,!UseCTB);
  464.     while (!UseCTB&&err==openFailed)
  465.     {
  466.         DestroyTrans();
  467.         if (isdigit(serverName[1])) {Fallback++;break;}    /* don't fallback on ip addresses. */
  468.         IncrementPhServer(serverName);
  469.         err=ConnectTrans(serverName,port,True);
  470.     }
  471.     if (err&&Fallback)
  472.     {
  473.         Fallback = 0;
  474.         SilenceTrans(False);
  475.         NotePhServer(GetRString(serverName,NOONE));
  476.     }
  477.     else if (Fallback)
  478.         NotePhServer(serverName);
  479.     return(err);
  480. }
  481.  
  482. /************************************************************************
  483.  * NotePhServer - tell the user who we're talking to.
  484.  ************************************************************************/
  485. void NotePhServer(UPtr serverName)
  486. {
  487.     Str255 msg;
  488.     ComposeRString(msg,PH_SUCCEED,serverName);
  489.     STEAppendText(msg+1,*msg,ASTE);
  490. }
  491.  
  492. /************************************************************************
  493.  * IncrementPhServer - go on to the next ph server
  494.  ************************************************************************/
  495. void IncrementPhServer(UPtr serverName)
  496. {
  497.     Str255 fmt,msg,newServer;
  498.     
  499.     Fallback++;
  500.     MakeFallbackName(newServer,Fallback);
  501.     GetRString(fmt,PH_FAIL);
  502.     utl_PlugParams(fmt,msg,serverName,newServer,nil,nil);
  503.     STEAppendText(msg+1,*msg,ASTE);
  504.     PCopy(serverName,newServer);
  505. }
  506.  
  507. /************************************************************************
  508.  * MakeFallbackName - add the appropriate numeral to a hostname
  509.  ************************************************************************/
  510. void MakeFallbackName(UPtr serverName, short fallback)
  511. {
  512.     char *spot;
  513.     Str15 num;
  514.  
  515.     GetPref(serverName,PREF_PH);
  516.     if (!*serverName) GetRString(serverName,PH_HOST);
  517.     if (fallback)
  518.     {
  519.         NumToString(fallback,num);
  520.         spot = strchr(serverName+1,'.');
  521.         if (!spot) spot=serverName+*serverName+1;
  522.         BlockMove(spot,spot+*num,*serverName-(spot-serverName)+2);
  523.         BlockMove(num+1,spot,*num);
  524.         *serverName += *num;
  525.     }
  526. }
  527.  
  528. /************************************************************************
  529.  * SendQiCommand - send the current command to qi
  530.  ************************************************************************/
  531. short SendQiCommand(UPtr cmd)
  532. {
  533.     return(SendTrans(2,cmd+1,*cmd,"\012",1));
  534. }
  535.  
  536. /************************************************************************
  537.  * GetQiResponse - read a response from the nameserver
  538.  ************************************************************************/
  539. short GetQiResponse(void)
  540. {
  541.     UHandle text = NuHandle(nil);
  542.     Str255 separator;
  543.     Str255 buffer;
  544.     long size;
  545.     short ordinal = 0;
  546.     short lastOrdinal = 0;
  547.     short response=600;
  548.     Boolean tooBig = False;
  549.     
  550.     /*
  551.      * do it
  552.      */
  553.     if (text)
  554.     {
  555.         GetRString(separator,PH_SEPARATOR);
  556.         do
  557.         {
  558.             size=sizeof(buffer);
  559.             response = QiLine(&ordinal,buffer,&size);
  560.             if (tooBig) continue;
  561.             if (response==598)
  562.             {
  563.                 Str63 query;
  564.                 GetRString(query,PH_QUERY);
  565.                 response = 0;
  566.                 if (SendTrans(3,query+1,*query,LDRef(QText),QLen,"\012",1))
  567.                     response = 600;
  568.                 UL(QText);
  569.                 continue;
  570.             }
  571.             if (ordinal != lastOrdinal)
  572.             {
  573.                 (void) PtrAndHand(separator+1,text,*separator);
  574.                 lastOrdinal = ordinal;
  575.             }
  576.             if (response < 600)
  577.                 if (size+GetHandleSize(text)<32000)
  578.                     (void) PtrAndHand(buffer,text,size);
  579.                 else
  580.                 {
  581.                     tooBig = True;
  582.                     GetRString(buffer,PH_TOO_BIG);
  583.                     (void) PtrAndHand(buffer+1,text,*buffer);
  584.                 }
  585.         }
  586.         while(response<200);
  587.         STEAppendText(LDRef(text),GetHandleSize(text),ASTE);
  588.         ZapHandle(text);
  589.     }
  590.     
  591.     if (text) DisposHandle(text);
  592.     return(response);
  593. }
  594.  
  595. /************************************************************************
  596.  * CloseQi - close the qi connection
  597.  ************************************************************************/
  598. void CloseQi(void)
  599. {
  600.     Str255 buffer;
  601.     long size;
  602.     Str63 quitCmd;
  603.         
  604.     GetRString(quitCmd,PH_QUIT);
  605.     /*
  606.      * do it
  607.      */
  608.     if (buffer && !SendTrans(2,quitCmd+1,*quitCmd,"\012",1))
  609.     {
  610.         for (size=sizeof(buffer);
  611.                  QiLine(nil,buffer,&size)<200;
  612.                  size=sizeof(buffer))
  613.             ;
  614.     }
  615.     
  616.     DisTrans();
  617. }
  618.  
  619. /************************************************************************
  620.  * QiLine - read a line from QI
  621.  ************************************************************************/
  622. int QiLine(short *ordinal, UPtr text, long *size)
  623. {
  624.     short result;
  625.     UPtr spot;
  626.     short ord;
  627.     
  628.     if (RecvLine(text,size)) return(600);
  629.     result = atoi(text);
  630.     if (!result)
  631.     {
  632.         *size = 0;
  633.         return(100);
  634.     }
  635.     for (spot=text;*spot!=':';spot++);
  636.     ord = 0;
  637.     for (spot++;*spot>='0' && *spot <= '9';spot++)
  638.         ord = ord * 10 + *spot - '0';
  639.     if (ord)
  640.     {
  641.         *size -= spot-text+1;
  642.         BlockMove(spot+1,text,*size);
  643.     }
  644.     if (ordinal) *ordinal = ord;
  645.     return(result);
  646. }
  647.  
  648. /************************************************************************
  649.  * PhSetSTE - set the text area
  650.  ************************************************************************/
  651. void PhSetSTE(STEHandle ste)
  652. {
  653.     if (Win->ste == ste) return;
  654.     if (Win->ste) {TEDeactivate((*(STEHandle)Win->ste)->te);}
  655.     Win->ste = ste;
  656.     TEActivate((*ste)->te);
  657.     Win->ro = ste==ASTE;
  658. }
  659.  
  660. /************************************************************************
  661.  * PhFixFont - fix the font in the Ph window
  662.  ************************************************************************/
  663. void PhFixFont(void)
  664. {
  665.     TEFixup((*ASTE)->te);
  666.     TEFixup((*QSTE)->te);
  667. }
  668.  
  669. /************************************************************************
  670.  * NewPhHost - install a new ph host
  671.  ************************************************************************/
  672. void NewPhHost(void)
  673. {
  674.     Str63 scratch;
  675.     Str127 newLabel;
  676.     if (PhGlobals)
  677.     {
  678.         GetPref(scratch,PREF_PH);
  679.         if (!*scratch) GetRString(scratch,PH_HOST);
  680.         ComposeRString(newLabel,PH_LABEL,scratch);
  681.         PCopy(Label,newLabel);
  682.         InvalContent(Win);
  683.         Fallback = 0;
  684.     }
  685. }
  686.  
  687.  
  688. /************************************************************************
  689.  * DoFinger - do the finger 'protocol'
  690.  ************************************************************************/
  691. void DoFinger(UPtr cmd)
  692. {
  693.     UPtr atSign = strchr(cmd+1,'@');
  694.     short uLen;
  695.     Str255 buffer;
  696.     long size;
  697.     Boolean gotSome=False;
  698.   
  699.     if (atSign)
  700.     {
  701.         uLen = atSign-cmd-1;
  702.         MakePStr(buffer,atSign+1,*cmd - uLen - 1);
  703.         buffer[*buffer+1] = 0;
  704.     }
  705.     else
  706.     {
  707.         GetSMTPInfo(buffer);
  708.         uLen = *cmd;
  709.     }
  710.     
  711.     if (!ConnectTrans(buffer,GetRLong(FINGER_PORT),False))
  712.     {
  713.         if (!SendTrans(2,uLen?cmd+1:" ",uLen?uLen:1,"\n\r",2))
  714.         {
  715.             SilenceTrans(True);
  716.             for (size=sizeof(buffer)-2;!NetRecvLine(buffer,&size);size=sizeof(buffer)-2)
  717.             {
  718.                 NoScrollTESetSelect(INFINITY,INFINITY,(*ASTE)->te);
  719.                 TEInsert(buffer,size,(*ASTE)->te); SFWTC = True;
  720.             }
  721.             NoScrollTESetSelect(0,0,(*ASTE)->te);
  722.             STETextChanged(ASTE);
  723.         }
  724.         DisTrans();
  725.     }
  726. }
  727.  
  728. #pragma segment Transport
  729. /************************************************************************
  730.  * RecvLine - get some text from the remote host.
  731.  ************************************************************************/
  732. int NetRecvLine(UPtr line,long *size)
  733. {
  734.     long count;
  735.     UPtr anchor, end;
  736.     short err;
  737.     static int RcvBufferSize;
  738.     long bSize = *size;
  739.     Byte c;
  740.     
  741.     *size = 0;
  742.     if (!RcvBufferSize) RcvBufferSize = GetHandleSize(RcvBuffer);
  743.  
  744.     anchor = line;
  745.     end = line+bSize-1;
  746.     while (anchor < end)                                         /* need more chars */
  747.         if (RcvSpot>=0)                                             /* there are some buffered chars */
  748.         {
  749.             UPtr rPtr = *RcvBuffer+RcvSpot;
  750.             if (!DontTranslate && TransIn)
  751.             {
  752.                 for(c=*rPtr++;anchor<end;c=*rPtr++)
  753.                     if (c && c!='\n')
  754.                     {
  755.                          *anchor++ = TransIn[c];
  756.                         if (c=='\r')
  757.                         {
  758.                             anchor[-1] = '\n';
  759.                             break;
  760.                         }
  761.                     }
  762.             }
  763.             else
  764.             {
  765.                 for(c=*rPtr++;anchor<end;c=*rPtr++)
  766.                     if (c && c!='\n')
  767.                     {
  768.                          *anchor++ = c;
  769.                         if (c=='\r')
  770.                         {
  771.                             anchor[-1] = '\n';
  772.                             break;
  773.                         }
  774.                     }
  775.             }
  776.             RcvSpot = rPtr - *RcvBuffer;
  777.             if (RcvSpot>RcvSize)                                    /* newline was sentinel */
  778.                 anchor--;
  779.             if (RcvSpot>=RcvSize)                                    /* we have emptied the buffer */
  780.                 RcvSpot = -1;
  781.             if (anchor[-1]=='\n' || anchor>=end)    /* found a valid newline, or filled buffer */
  782.             {
  783.                 *size = anchor-line;
  784.                 *anchor = 0;                                        /* terminate */
  785.                 return(noErr);
  786.             }
  787.         }
  788.         else
  789.         {
  790.             count = RcvBufferSize-1;
  791.             if (err=RecvTrans(LDRef(RcvBuffer),&count))     /* get some chars */
  792.                  count=0;
  793.             UL(RcvBuffer);
  794.             if (count)
  795.             {
  796.                 (*RcvBuffer)[count] = '\r';                                             /* sentinel */
  797.                 RcvSize = count;
  798.                 RcvSpot = 0;
  799.             }
  800.             if (err)
  801.             {
  802.                 *size = anchor-line;
  803.                 line[*size] = 0;
  804.                 return(err);
  805.             }
  806.         }
  807.     *size = anchor - line;
  808.     if (*size) line[*size] = 0;                     /* null terminate */
  809.     return(*size ? noErr : err);
  810. }
  811.  
  812.  
  813. #pragma segment Balloon
  814. /************************************************************************
  815.  * PhHelp - do balloon help for the ph window
  816.  ************************************************************************/
  817. void PhHelp(MyWindowPtr win,Point mouse)
  818. {
  819. #pragma unused(win)
  820.     Rect r;
  821.     short hnum=UseCTB?9:(PrefIsSet(PREF_FINGER)?5:1);
  822.     
  823.     r = QRect;
  824.     if (PtInRect(mouse,&r))
  825.         ;
  826.     else
  827.     {
  828.         hnum++;
  829.         r = ARect;
  830.         if (PtInRect(mouse,&r))
  831.             ;
  832.         else
  833.         {
  834.             hnum++;
  835.             r = (*OkButton)->contrlRect;
  836.             if (PtInRect(mouse,&r))
  837.                 ;
  838.             else
  839.             {
  840.                 hnum++;
  841.                 r = (*FingerButton)->contrlRect;
  842.                 if (PtInRect(mouse,&r))
  843.                     ;
  844.                 else hnum=100;    /* off the end of the scale */
  845.             }
  846.         }
  847.     }
  848.     HelpRect(&r,PHWIN_HELP_STRN+hnum,100);
  849. }